Skip to main content

第33章 结构体与联合体

在C++中,结构体(Struct)和联合体(Union)是两种用户自定义的数据类型,用于将不同类型的数据组合在一起,方便数据的管理和操作。结构体适用于存储多个相关但不同类型的数据,而联合体则通过共享内存空间存储不同类型的数据。

33.1 结构体(Struct)

33.1.1 结构体的定义

结构体语法:

struct 结构体名{
成员类型1 成员名1;
成员类型2 成员名2;
// ...更多成员
};

示例:定义学生结构体

struct Student{
string name;//姓名
int age;//年龄
float score;//成绩
char gender;//性别('M'男,'F'女)
};

33.1.2 结构体变量的定义与初始化

  1. 定义结构体同时创建变量
struct Teacher{
string name;
int id;
} t1,t2;
  1. 先定义结构体,后创建变量
struct Student{
string name;
int age;
};
Student s1, s2;
  1. 初始化 顺序初始化:
Student s3 = {"张三", 18};

C++11指定成员初始化(顺序不限):

Student s4 = {.age = 19, .name = "李四"};

33.1.3 结构体成员访问

  • 普通结构体变量:. 成员访问符
  • 结构体指针:-> 箭头访问符
struct Student{
string name;
int age;
};
int main(){
Student s={"王五", 20};
Student* p= &s;
// 普通变量访问
cout<<"姓名:"<<s.name<<",年龄:"<<s.age<<endl;
// 指针访问
cout<<"姓名:"<<p->name<<",年龄:"<<p->age;
s.age = 21;
p->name="赵六";
return 0;
}

33.1.4 结构体数组

多个结构体组成数组,每一个数组元素都是结构体:

struct Book {
string title;//书名
string author;//作者
float price;//价格
};
int main(){
Book books[3]={
{"C++ Primer", "Lippman", 89.0f},
{"算法导论","CLRS",128.0f},
{"编程珠玑","Bentley",59.0f}
};
for(int i=0;i<3;i++){
cout<<"书名:"<<books[i].title
<<",作者:"<<books[i]
<<",价格:"<<books[i].price<<endl;
}
return 0;
}

33.1.5 结构体作为函数参数/返回值

  1. 值传递:拷贝完整结构体副本
struct Point{
int x;
int y;
};
void printPoint(Point p){
cout<<"("<<p.x<<","<<p.y<<")";
}
  1. 引用传递:不拷贝,可修改原结构体
void movePoint(Point& p, int dx, int dy){
p.x += dx;
p.y += dy;
}
  1. 函数返回结构体
Point createPoint(int x, int y){
Point p={x,y};
return p;
}
int main(){
Point p=createPoint(3,4);
printPoint(p);
movePoint(p,2,5);
printPoint(p);
return 0;
}

33.1.6 结构体嵌套

结构体成员可以是另一个结构体,用于复杂数据描述:

struct Date{
int year;
int month;
int day;
};
struct Employee{
string id;
string name;
Date hireDate;//嵌套日期结构体
float salary;
};
int main(){
Employee emp={
"E001",
"张三",
{2020,3,15},
8000.0f
};
cout<<"入职日期:"
<<emp.hireDate.year<<"-"
<<emp.hireDate.month<<"-"
<<emp.hireDate.day;
return 0;
}

33.2 联合体(Union)

33.2.1 联合体定义

联合体所有成员共享同一块内存,同一时刻只能存储其中一个成员。 语法:

union 联合体名{
成员类型1 成员1;
成员类型2 成员2;
};

示例:

union Data{
int i;
float f;
char c;
};

33.2.2 联合体变量使用

int main(){
Data d;
d.i=100;
cout<<"d.i="<<d.i<<endl;
d.f=3.14f;
cout<<"d.f="<<d.f<<endl;
d.c='A';
cout<<"d.c="<<d.c<<endl;
return 0;
}

修改一个成员会覆盖内存中其他成员的值,其他成员读取无意义。

33.2.3 联合体内存大小

联合体占用内存等于最大成员的字节数。

union SizeTest{
char a;//1字节
int b;//4字节
double c;//8字节
};
// sizeof(SizeTest) = 8

33.2.4 联合体应用场景

  1. 节省内存:不同时刻只用一种数据;
  2. 二进制数据解析、底层类型内存查看; 示例:浮点数内存转整数查看
union Converter{
float f;
int i;
};
int main(){
Converter conv;
conv.f=3.14f;
cout<<conv.i;
return 0;
}

33.3 结构体与联合体核心区别

对比项结构体 struct联合体 union
内存分配所有成员独立分配,内存叠加所有成员共享同一块内存
存储特性所有成员可同时存储有效值同一时间仅一个成员有效
大小所有成员内存之和(含对齐填充)等于最大成员字节数
使用场景存储一组关联不同属性数据同一内存复用,节省空间